﻿using SQLite;
using StudentLive.Common;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.ApplicationModel.Resources;
using Windows.Networking.Connectivity;
using Windows.Storage;
using Windows.Storage.FileProperties;
using Windows.UI;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;

namespace StudentLive.DataModel
{
    [Windows.Foundation.Metadata.WebHostHidden]
    //[DataContractAttribute]
    public abstract class DataItem : StudentLive.Common.BindableBase
    {
        public virtual void updateDatabaseItem() { }

        internal static Uri _baseUri = new Uri("ms-appx:///");
        private static ColorManager Colors = new ColorManager();

        public DataItem(String name, String description)
        {
            this._name = name;
            this._description = description;
        }

        private SolidColorBrush _color;

        //[Sqlite. IgnoreDataMember]
        public SolidColorBrush Color
        {
            get { return this._color; }
            set { this.SetProperty(ref this._color, value); }
        }

        private int _colorIndex = 0;
        //[DataMember]
        public int ColorIndex
        {
            get { return _colorIndex; }
            set
            {
                _color = Colors.GetColor(value);
                _colorIndex = value;
            }
        }

        /// <summary>This is mainly here to aid in binding to the standard templates, which expect a title property</summary>
        public string Title
        {
            get { return this.Name; }
        }

        private string _name = string.Empty;
        //[DataMember]
        public string Name
        {
            get { return this._name; }
            set { this.SetProperty(ref this._name, value); }
        }

        private string _description = string.Empty;
        //[DataMember]
        public string Description
        {
            get
            {
                if (_description == string.Empty)
                {
                    _description = this._name;
                }
                return this._description;

            }
            set { this.SetProperty(ref this._description, value); }
        }

        public int AssignNextColor()
        {
            ColorIndex = Colors.AssignNextIndex();
            return _colorIndex;
        }

        /// <summary>Manage the pool of colors that are assigned to topics</summary>
        private class ColorManager
        {
            private List<Color> TopicColors = new List<Color>(){
                //ColorHelper.FromArgb(255,45,69,43),
                //ColorHelper.FromArgb(255,124,170,59),
                //ColorHelper.FromArgb(255,133,93,46),
                //ColorHelper.FromArgb(255,170,65,59),
                //ColorHelper.FromArgb(255,110,171,186),
                //ColorHelper.FromArgb(255,59,103,170),
                //ColorHelper.FromArgb(255,153,110,186),
                //ColorHelper.FromArgb(255,25,34,45)   
                ColorHelper.FromArgb(255,61,54,103),//
                ColorHelper.FromArgb(255,113,66,102),//
                ColorHelper.FromArgb(255,130,61,180),//#823db4
                ColorHelper.FromArgb(255,200,77,95),//
                ColorHelper.FromArgb(255,221,194,63),//#ddc23f
                ColorHelper.FromArgb(255,133,197,162),//85C5A2
                ColorHelper.FromArgb(255,127,206,69),
                ColorHelper.FromArgb(255,61,54,103)   

            };

            private int nextColor = 0;

            public int AssignNextIndex()
            {
                return nextColor++;
            }

            public SolidColorBrush GetColor(int index)
            {
                if (index >= TopicColors.Count)
                {
                    index = 0;
                    nextColor = 0;
                }

                return (new SolidColorBrush(TopicColors[index]));
            }
        }
    }

    #region Shared Materials Items

    public class CoursePlanItem : DataItem
    {
        #region Constructors
        public CoursePlanItem()
            : base(String.Empty, String.Empty)
        { }

        public CoursePlanItem(SqlCoursePlan sqlItem)
            : this(sqlItem.Name, sqlItem.Name)
        {
            _sqlCoursePlan = sqlItem;
        }

        public CoursePlanItem(String name, String description)
            : base(name, description)
        { }
        #endregion

        private ObservableCollection<UnitItem> _units = new ObservableCollection<UnitItem>();

        public ObservableCollection<UnitItem> Units
        {
            get { return this._units; }
        }
        public IEnumerable<UnitItem> HubUnits
        {
            get
            {
                // Customized units for the hub page! :)
                var hubUnits = this._units.OrderBy<UnitItem, int>(u => u.UnitID).Take<UnitItem>(6);

                int unitIndex = 0;
                foreach (var item in hubUnits)
                {
                    switch (unitIndex)
                    {
                        case 0:
                            item.RowSpan = 2; item.ColSpan = 2;
                            break;
                        default:
                            item.RowSpan = 1; item.ColSpan = 1;
                            break;
                    }

                    unitIndex++;
                }

                return hubUnits;
            }
        }

        private SqlCoursePlan _sqlCoursePlan;
        public SqlCoursePlan DatabaseItem { get { return this._sqlCoursePlan; } }

        private ImageSource _image;

        public ImageSource Image
        {
            get
            {
                if (this._image == null && this._sqlCoursePlan.ImagePath != null)
                {
                    this._image = new BitmapImage(new Uri(DataItem._baseUri, this._sqlCoursePlan.ImagePath));
                }

                return this._image;
            }

            set
            {
                this.SetProperty(ref this._image, value);
            }
        }

        public int CoursePlanID
        {
            get { return this._sqlCoursePlan.CoursePlanID; }

            set
            {
                if (!object.Equals(this._sqlCoursePlan.CoursePlanID, value))
                {
                    this._sqlCoursePlan.CoursePlanID = value;
                    this.OnPropertyChanged("CoursePlanID");
                }
            }
        }

        public ObservableCollection<HubGroups.HubGroup> SnappedItems
        {
            get { return LiveDataSource.GetAllItemsOfCoursePlan(CoursePlanID); }
        }


    }
    public class UnitItem : DataItem
    {
        #region Constructors
        public UnitItem()
            : this("Unit", "I am the description of this unit")
        { }

        public UnitItem(SqlUnit sqlItem) :
            this(sqlItem.Name, sqlItem.Name)
        {
            _sqlUnit = sqlItem;
        }
        public UnitItem(String name, String description)
            : base(name, description)
        { }
        #endregion


        private SqlUnit _sqlUnit;
        public SqlUnit DatabaseItem { get { return this._sqlUnit; } }

        private int _colSpan = 2;
        private int _rowSpan = 1;

        public int ColSpan
        {
            get { return this._colSpan; }
            set { this.SetProperty(ref this._colSpan, value); }
        }
        public int RowSpan
        {
            get { return this._rowSpan; }
            set { this.SetProperty(ref this._rowSpan, value); }
        }

        public int UnitID
        {
            get { return this._sqlUnit.UnitID; }

            set
            {
                if (!object.Equals(this._sqlUnit.UnitID, value))
                {
                    this._sqlUnit.UnitID = value;
                    this.OnPropertyChanged("UnitID");
                }
            }
        }
        public int CoursePlanID
        {
            get { return this._sqlUnit.CoursePlanID; }

            set
            {
                if (!object.Equals(this._sqlUnit.CoursePlanID, value))
                {
                    this._sqlUnit.CoursePlanID = value;
                    this.OnPropertyChanged("CoursePlanID");
                }
            }
        }

        public string Icon
        {
            get { return this._sqlUnit.Icon; }
        }

        public int LessonsCount
        {
            get { return this.Lessons.Count; }
        }

        private ObservableCollection<LessonPlanItem> _lessons = new ObservableCollection<LessonPlanItem>();
        public ObservableCollection<LessonPlanItem> Lessons { get { return _lessons; } }
        public CoursePlanItem CoursePlan { get; set; }

        public Brush SelectedItemBackgroundColor
        {
            get
            {
                return new SolidColorBrush(Windows.UI.Color.FromArgb(255, 208, 116, 16));//Fill="#FFD07410"
            }
        }

    }
    public class LessonPlanItem : DataItem
    {
        #region Constructors
        public LessonPlanItem()
            : this("Lesson Plan", "I am the description of this lesson plan")
        { }

        public LessonPlanItem(SqlLessonPlan sqlItem)
            : this(sqlItem.Name, sqlItem.Name)
        {
            _sqlLessonPlan = sqlItem;
        }

        public LessonPlanItem(String name, String description)
            : base(name, description)
        {
            _resources.CollectionChanged += delegate { SubTitle = String.Format(" {0}", _resources.Count); this._resourcesMirror = this._resources.OrderBy(res => res.DatabaseItem.PrimaryKey); };
            _resources.CollectionChanged += delegate { Description = String.Format("There are {0} Resource(s) in that lesson", _resources.Count); };
        }

        public int ResourcesCount
        {
            get { return this.Resources.Count; }
        }
        #endregion

        private SqlLessonPlan _sqlLessonPlan;
        public SqlLessonPlan DatabaseItem { get { return this._sqlLessonPlan; } }

        private ObservableCollection<ResourceItem> _resources = new ObservableCollection<ResourceItem>();
        public ObservableCollection<ResourceItem> Resources { get { return _resources; } }

        private IOrderedEnumerable<ResourceItem> _resourcesMirror;
        public IOrderedEnumerable<ResourceItem> ResourcesMirror
        {
            get
            {
                return this._resourcesMirror;
            }
            set { this.SetProperty(ref this._resourcesMirror, value); }
        }

        public string SubTitle { get; set; }

        public int UnitID { get; set; }

        public UnitItem Unit { get; set; }

        public int LessonPlanID { get { return this._sqlLessonPlan.LessonPlanID; } }

        public Brush SelectedItemBackgroundColor
        {
            get
            {
                return new SolidColorBrush(Windows.UI.Color.FromArgb(255, 20, 156, 7));//Fill="#FFD07410" #149C07
            }
        }
    }
    public class ResourceItem : DataItem
    {
        #region Constructors
        public ResourceItem() : this(string.Empty, string.Empty) { }

        public ResourceItem(SqlLearningResource sqlItem)
            : this(sqlItem.LearningResourceName, sqlItem.Description)
        {
            _sqlResource = sqlItem;
            this._isDownloaded = sqlItem.IsDownloaded;
            this._isFavoured = sqlItem.IsFavored;
            this._rate = sqlItem.Rate;
        }

        public ResourceItem(String name, String description)
            : base(name, description)
        { }
        #endregion

        public SqlLearningResource DatabaseItem { get { return this._sqlResource; } }

        private SqlLearningResource _sqlResource;
        private bool _isDownloaded;
        public bool IsDownloaded
        {
            get { return this._isDownloaded; }
            set { if (this.SetProperty(ref this._isDownloaded, value)) this.OnPropertyChanged("Image"); }
        }

        private bool _isFavoured;
        public bool IsFavoured
        {
            get { return this._isFavoured; }
            set { this.SetProperty(ref this._isFavoured, value); }
        }

        private double _rate;
        public double Rate
        {
            get { return this._rate; }
            set { this.SetProperty(ref this._rate, value); }
        }

        private string _localPath = String.Empty;
        public string LocalPath
        {
            get
            {
                if (_localPath == null || _localPath == string.Empty)
                {
                    _localPath = this._sqlResource.LocalPath;
                }
                return this._localPath;
            }

            set
            {
                this.SetProperty(ref this._localPath, value);
            }
        }

        private string _resourceGuid = String.Empty;
        public string ResourceGUID
        {
            get
            {
                if (this._resourceGuid == String.Empty)
                    this._resourceGuid = this._sqlResource.LearningResourceGUID;

                return this._resourceGuid;
            }
            set
            {
                this.SetProperty(ref this._resourceGuid, value);
            }
        }

        public object LessonPlanID { get; set; }

        public LessonPlanItem Lesson { get; set; }

        private void GetThumbnail()
        {
            if (IsDownloaded)
            {
                string imagePath = string.Empty;
                string ext = LocalPath.Split('.').Last();
                if (ext == "pdf")
                {
                    imagePath = Constants.GetResourceThumbnailWithResourceType(Constants.ResourcesTypes.pdf);
                }
                else if (ext == "doc" || ext == "docx")
                {
                    imagePath = Constants.GetResourceThumbnailWithResourceType(Constants.ResourcesTypes.word);
                }
                else if (ext == "ppt" || ext == "pptx")
                {
                    imagePath = Constants.GetResourceThumbnailWithResourceType(Constants.ResourcesTypes.ppt);
                }
                else if (ext == "xls" || ext == "xlsx")
                {
                    imagePath = Constants.GetResourceThumbnailWithResourceType(Constants.ResourcesTypes.excel);
                }
                this._imagePath = imagePath;
                //Image = new BitmapImage(new Uri(DataItem._baseUri, imagePath));
                //StorageFile file = await StorageFile.GetFileFromPathAsync(Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, LocalPath));
                //if (file != null)
                //{
                //    const ThumbnailMode thumbnailMode = ThumbnailMode.SingleItem;
                //    const uint size = 110;
                //    using (StorageItemThumbnail thumbnail = await file.GetThumbnailAsync(thumbnailMode, size))
                //    {
                //        if (thumbnail != null)
                //        {
                //            BitmapImage bitmapImage = new BitmapImage();
                //            bitmapImage.SetSource(thumbnail);
                //            Image = bitmapImage;
                //        }
                //    }
                //}
            }
            else
            {
                _image = null;
                _imagePath = "Assets\\CloudDocument.png";
            }
        }
        private ImageSource _image = null;
        private String _imagePath = null;

        public ImageSource Image
        {
            get
            {
                GetThumbnail();

                if (this._image == null && this._imagePath != null)
                {
                    this._image = new BitmapImage(new Uri(DataItem._baseUri, this._imagePath));
                }

                return this._image;
            }

            set
            {
                this._imagePath = null;
                this.SetProperty(ref this._image, value);
            }
        }


        public void SetImage(String path)
        {
            this._image = null;
            this._imagePath = path;
            this.OnPropertyChanged("Image");
        }

        public override void updateDatabaseItem()
        {
            this._sqlResource.IsDownloaded = this._isDownloaded;
            this._sqlResource.IsFavored = this._isFavoured;
            this._sqlResource.Rate = this.Rate;
            this._sqlResource.LocalPath = this.LocalPath;
            this._sqlResource.LocalPath = this.Description;
        }
    }
    public class TeachersGroup : DataItem
    {
        public TeachersGroup() : this(string.Empty, string.Empty) { }

        public TeachersGroup(String name, String description)
            : base(name, description)
        { }

        public IEnumerable<TeacherItem> Teachers
        {
            get
            {
                List<TeacherItem> teachersList = new List<TeacherItem>();
                teachersList.Add( new TeacherItem("Assets/Teachers/manteacher1.jpg") { FirstName = "Abdallah", LastName = "Sameh", Description = "Arabic Teacher",Email = "abdallah.sameh@hotmail.com", ImageURL = "http://a0.twimg.com/profile_images/2422096641/ablqp7zzx9bk78kdzw0v_reasonably_small.jpeg"});
                teachersList.Add(new TeacherItem("Assets/Teachers/womenteacher1.jpg") { FirstName = "Khadija", LastName = "Mohamed", Description = "English Teacher", Email = "khadija.mohamed@hotmail.com", ImageURL = "http://profile.ak.fbcdn.net/hprofile-ak-snc6/260968_551702233_1088605994_n.jpg" });  
                teachersList.Add(new TeacherItem("Assets/Teachers/manteacher2.jpg") { FirstName = "Ahmed", LastName = "Kareem",Description = "Science Teacher", Email = "ahmed.kareem@hotmail.com", ImageURL = "http://profile.ak.fbcdn.net/hprofile-ak-snc6/260968_551702233_1088605994_n.jpg"});
                teachersList.Add(new TeacherItem("Assets/Teachers/manteacher3.jpg") { FirstName = "Youssef", LastName = "Abdallah", Description = "Math Teacher", Email = "Youssef.Abdallah@hotmail.com", ImageURL = "http://a0.twimg.com/profile_images/2422096641/ablqp7zzx9bk78kdzw0v_reasonably_small.jpeg" });  
              
                return teachersList;
            }
        }
}

    public class StudentsGroup : DataItem
    {
        public StudentsGroup() : this(string.Empty, string.Empty) { }

        public StudentsGroup(String name, String description)
            : base(name, description)
        { }


        public IEnumerable<StudentItem> Students
        {
            get
            {
                List<StudentItem> studentsList = new List<StudentItem>();
                studentsList.Add(new StudentItem("Assets/Students/Ahmed.jpg", "Amr", "Mohamed") { Description = "Arabic & English", Email = "amr.mohmaed@hotmail.com", Subtitle = "Classes in Common:", ColorIndex = 5, ImageURL = "http://qph.is.quoracdn.net/main-thumb-2700592-200-35Mp2X1PNvFBoVfIhx9hLibEGdkvN511.jpeg" });
                studentsList.Add(new StudentItem("Assets/Students/Ali.jpg", "Abdelrahman", "Adel") { Description = "English", Email = "abdelrahman.adel@hotmail.com", Subtitle = "Classes in Common:", ColorIndex = 5, ImageURL = "http://qph.is.quoracdn.net/main-thumb-2700592-200-35Mp2X1PNvFBoVfIhx9hLibEGdkvN511.jpeg" });
                studentsList.Add(new StudentItem("Assets/Students/Amran.jpg", "Ahmad", "AlMoraly") { ImageURL = "https://lh4.googleusercontent.com/-FXqnP1KDePg/ThtOMg_sgeI/AAAAAAAAAE0/O9WmcQtGee8/s347/270383_10150247311926513_554461512_7836073_1066157_n.jpg", Description = "Arabic", Email = "ahmad.almoraly@hotmail.com", Subtitle = "Classes in Common:", ColorIndex = 5 });
                studentsList.Add(new StudentItem("Assets/Students/Khalifa.jpg", "Kamel", "Nabil") { Email = "kamel.nabil@hotmail.com", Subtitle = "Classes in Common:", Description = "Arabic", ColorIndex = 5, ImageURL = "https://lh6.googleusercontent.com/-cN3GHNhV7GY/T-L4ooJ0JLI/AAAAAAAAAHc/sbUclDVYses/s800/Me+00+056.JPG" });
                studentsList.Add(new StudentItem("Assets/Students/Rashed.jpg", "Akram", "Sayed") { Description = "Math", Email = "akram.sayed@hotmail.com", Subtitle = "Classes in Common:", ColorIndex = 5, ImageURL = "http://qph.is.quoracdn.net/main-thumb-2700592-200-35Mp2X1PNvFBoVfIhx9hLibEGdkvN511.jpeg" });
                studentsList.Add(new StudentItem("Assets/Students/Student12.jpg", "Sherif", "Adel") { Description = "Math", Email = "sherif.adel@hotmail.com", Subtitle = "Classes in Common:", ColorIndex = 5, ImageURL = "http://qph.is.quoracdn.net/main-thumb-2700592-200-35Mp2X1PNvFBoVfIhx9hLibEGdkvN511.jpeg" });
                studentsList.Add(new StudentItem("Assets/Students/Amran.jpg", "Ahmad", "Mohammed") { ImageURL = "https://lh4.googleusercontent.com/-FXqnP1KDePg/ThtOMg_sgeI/AAAAAAAAAE0/O9WmcQtGee8/s347/270383_10150247311926513_554461512_7836073_1066157_n.jpg", Description = "Arabic", Email = "ahmad.mohamed@live.com", Subtitle = "Classes in Common:", ColorIndex = 5 });
                studentsList.Add(new StudentItem("Assets/Students/Khalifa.jpg", "Kamel", "Nabil") { Email = "kamel.nabil@hotmail.com", Subtitle = "Classes in Common:", Description = "Arabic", ColorIndex = 5, ImageURL = "https://lh6.googleusercontent.com/-cN3GHNhV7GY/T-L4ooJ0JLI/AAAAAAAAAHc/sbUclDVYses/s800/Me+00+056.JPG" });
                studentsList.Add(new StudentItem("Assets/Students/Rashed.jpg", "Akram", "Sayed") { Description = "Math", Email = "akram.sayed@hotmail.com", Subtitle = "Classes in Common:", ColorIndex = 5, ImageURL = "http://qph.is.quoracdn.net/main-thumb-2700592-200-35Mp2X1PNvFBoVfIhx9hLibEGdkvN511.jpeg" });
                studentsList.Add(new StudentItem("Assets/Students/Student12.jpg", "Sherif", "Adel") { Description = "Math", Email = "sherif.adel@hotmail.com", Subtitle = "Classes in Common:", ColorIndex = 5, ImageURL = "http://qph.is.quoracdn.net/main-thumb-2700592-200-35Mp2X1PNvFBoVfIhx9hLibEGdkvN511.jpeg" });
                studentsList.Add(new StudentItem("Assets/Students/Ahmed.jpg", "Amr", "ElSehemy") { Description = "Arabic & English", Email = "amr.elsehemy@hotmail.com", Subtitle = "Classes in Common:", ColorIndex = 5, ImageURL = "http://qph.is.quoracdn.net/main-thumb-2700592-200-35Mp2X1PNvFBoVfIhx9hLibEGdkvN511.jpeg" });
                studentsList.Add(new StudentItem("Assets/Students/Ali.jpg", "Abdelrahman", "Aly") { Description = "English", Email = "bdelrahman.aly@live.com", Subtitle = "Classes in Common:", ColorIndex = 5, ImageURL = "http://qph.is.quoracdn.net/main-thumb-2700592-200-35Mp2X1PNvFBoVfIhx9hLibEGdkvN511.jpeg" });
                studentsList.Add(new StudentItem("Assets/Students/Amran.jpg", "Ahmad", "Aly") { ImageURL = "https://lh4.googleusercontent.com/-FXqnP1KDePg/ThtOMg_sgeI/AAAAAAAAAE0/O9WmcQtGee8/s347/270383_10150247311926513_554461512_7836073_1066157_n.jpg", Description = "Arabic", Email = "ahmad.aly@hotmail.com", Subtitle = "Classes in Common:", ColorIndex = 5 });
                studentsList.Add(new StudentItem("Assets/Students/Khalifa.jpg", "Kamel", "Nabil") { Email = "kamel.nabil@hotmail.com", Subtitle = "Classes in Common:", Description = "Arabic", ColorIndex = 5, ImageURL = "https://lh6.googleusercontent.com/-cN3GHNhV7GY/T-L4ooJ0JLI/AAAAAAAAAHc/sbUclDVYses/s800/Me+00+056.JPG" });
                studentsList.Add(new StudentItem("Assets/Students/Rashed.jpg", "Akram", "Sayed") { Description = "Math", Email = "akram.sayed@hotmail.com", Subtitle = "Classes in Common:", ColorIndex = 5, ImageURL = "http://qph.is.quoracdn.net/main-thumb-2700592-200-35Mp2X1PNvFBoVfIhx9hLibEGdkvN511.jpeg" });
                studentsList.Add(new StudentItem("Assets/Students/Student12.jpg", "Sherif", "Adel") { Description = "Math", Email = "sherif.adel@hotmail.com", Subtitle = "Classes in Common:", ColorIndex = 5, ImageURL = "http://qph.is.quoracdn.net/main-thumb-2700592-200-35Mp2X1PNvFBoVfIhx9hLibEGdkvN511.jpeg" });
                studentsList.Add(new StudentItem("Assets/Students/Student13.jpg", "Ahmad", "AlMoraly") { ImageURL = "https://lh4.googleusercontent.com/-FXqnP1KDePg/ThtOMg_sgeI/AAAAAAAAAE0/O9WmcQtGee8/s347/270383_10150247311926513_554461512_7836073_1066157_n.jpg", Description = "Science", Email = "ahmad.almoraly@hotmail.com", Subtitle = "Classes in Common:", ColorIndex = 5 });
                studentsList.Add(new StudentItem("Assets/Students/Student14.jpg", "Ramy", "Medhat") { Description = "Math", Subtitle = "Classes in Common:", Email = "ramy.medhat@hotmail.com", ColorIndex = 4, ImageURL = "https://uwaterloo.ca/embedded-software-group/sites/ca.embedded-software-group/files/uploads/images/Ramy-Medhat_1.jpg" });
                return studentsList;
            }
        }
    }




    #endregion

    #region Others

    public class SharedMaterialsItem : DataItem
    {

        #region Constructors
        public SharedMaterialsItem() : this(string.Empty, string.Empty) { }

        public SharedMaterialsItem(SqlSharedMaterials sqlItem)
            : this(sqlItem.SharedMaterialName, sqlItem.SharedMaterialDescription)
        {
            _sqlSharedMaterials = sqlItem;
        }

        public SharedMaterialsItem(String name, String description)
            : base(name, description)
        { }
        #endregion

        public SqlSharedMaterials DatabaseItem { get { return this._sqlSharedMaterials; } }

        private SqlSharedMaterials _sqlSharedMaterials;

        private string _localPath = String.Empty;
        public string LocalPath
        {
            get
            {
                if (_localPath == null || _localPath == string.Empty)
                {
                    _localPath = this._sqlSharedMaterials.LocalPath;
                }
                return this._localPath;
            }

            set
            {
                this.SetProperty(ref this._localPath, value);
            }
        }

        public ImageSource Icon
        {
            get
            {
                ImageSource icon = new BitmapImage(new Uri(DataItem._baseUri, "Assets\\Logo.png"));
                string fileExtension = Path.GetExtension(LocalPath).Trim('.');
                Constants.ResourcesTypes type = (Constants.ResourcesTypes)Enum.Parse(typeof(Constants.ResourcesTypes), fileExtension, true);

                if (type == Constants.ResourcesTypes.avi || type == Constants.ResourcesTypes.mp3)
                {
                    icon = new BitmapImage(new Uri(DataItem._baseUri, "Assets\\Logo.png"));
                }
                if (type == Constants.ResourcesTypes.pdf)
                {
                    icon = new BitmapImage(new Uri(DataItem._baseUri, "Assets\\pdf.png"));
                }
                if (type == Constants.ResourcesTypes.excel)
                {
                    icon = new BitmapImage(new Uri(DataItem._baseUri, "Assets\\excel.png"));
                }
                if (type == Constants.ResourcesTypes.ppt)
                {
                    icon = new BitmapImage(new Uri(DataItem._baseUri, "Assets\\ppt.png"));
                }
                if (type == Constants.ResourcesTypes.word)
                {
                    icon = new BitmapImage(new Uri(DataItem._baseUri, "Assets\\word.png"));
                }
                return icon;


            }
        }

    }

    public class NotifcationItem : DataItem
    {
        #region Constructors
        public NotifcationItem()
            : base(String.Empty, String.Empty)
        { }

        public NotifcationItem(String name, String description)
            : base(name, description)
        { }

        public NotifcationItem(SqlNotifications sqlItem)
            : this(sqlItem.Name, sqlItem.Description)
        {
            this._sqlNotifications = sqlItem;
        }
        #endregion

        SqlNotifications _sqlNotifications;

        Constants.NotificationTypes _type = 0;
        public Constants.NotificationTypes Type
        {
            get
            {
                if (this._type == 0)
                {
                    this._type = (Constants.NotificationTypes)this._sqlNotifications.Type;
                }
                return this._type;
            }
            set { this.SetProperty(ref this._type, value); }
        }

        public ImageSource Icon
        {
            get
            {
                return new BitmapImage(new Uri(DataItem._baseUri, Constants.GetNotificationIconWithType(Type)));
            }
        }
    }

    public class AssignmentItem : DataItem
    {
        #region Constructors
        public AssignmentItem()
            : base(String.Empty, String.Empty)
        { }

        public AssignmentItem(String name, String description)
            : base(name, description)
        { }
        #endregion
    }

    public class TeacherItem : DataItem
    {
        #region Constructors
        public TeacherItem(string imagePath)
            : base(String.Empty, String.Empty)
        {
            this._imagePath = imagePath;
        }

        public TeacherItem(string imagePath,string firstName, string lastName)
            : base(firstName +" "+ lastName, String.Empty)
        {
            this._imagePath = imagePath;
            this.FirstName = firstName;
            this.LastName = lastName;
        }


        public TeacherItem(String name, String description)
            : base(name, description)
        { }
        #endregion
        private string _firstName = string.Empty;
        public string FirstName
        {
            get { return this._firstName; }
            set { this.SetProperty(ref this._firstName, value); }
        }


        private string _lastName = string.Empty;
        public string LastName
        {
            get { return this._lastName; }
            set { this.SetProperty(ref this._lastName, value); }
        }

        public string FullName
        {
            get { return string.Format("{0} {1}", FirstName, LastName); }
        }

        private string _email = string.Empty;
        public string Email
        {
            get { return this._email; }
            set { this.SetProperty(ref this._email, value); }
        }

        private string _subtitle = string.Empty;
        public string Subtitle
        {
            get { return this._subtitle; }
            set { this.SetProperty(ref this._subtitle, value); }
        }

        private ImageSource _image = null;
        private String _imagePath = null;
        public ImageSource Image
        {
            get
            {
                if (this._image == null && this._imagePath != null)
                {
                    this._image = new BitmapImage(new Uri(StudentItem._baseUri, this._imagePath));
                }
                return this._image;
            }

            set
            {
                this._imagePath = null;
                this.SetProperty(ref this._image, value);
            }
        }

        public void SetImage(String path)
        {
            this._image = null;
            this._imagePath = path;
            this.OnPropertyChanged("Image");
        }

        private string _imageURL = string.Empty;
        public string ImageURL
        {
            get { return this._imageURL; }
            set { this.SetProperty(ref this._imageURL, value); }
        }

    }

    public class StudentItem : DataItem
    {
        #region Constructors
        public StudentItem(string imagePath)
            : base(String.Empty, String.Empty)
        {
            this._imagePath = imagePath;
        }
        public StudentItem(string imagePath,string firstName, string lastName)
            : base(firstName+" "+lastName, String.Empty)
        {
            this.FirstName = firstName;
            this.LastName = lastName;
            this._imagePath = imagePath;
        }

        #endregion

        private string _firstName = string.Empty;
        public string FirstName
        {
            get { return this._firstName; }
            set { this.SetProperty(ref this._firstName, value); }
        }

        private string _lastName = string.Empty;
        public string LastName
        {
            get { return this._lastName; }
            set { this.SetProperty(ref this._lastName, value); }
        }

        public string FullName
        {
            get { return string.Format("{0} {1}", FirstName, LastName); }
        }

        private string _email = string.Empty;
        public string Email
        {
            get { return this._email; }
            set { this.SetProperty(ref this._email, value); }
        }

        private string _subtitle = string.Empty;
        public string Subtitle
        {
            get { return this._subtitle; }
            set { this.SetProperty(ref this._subtitle, value); }
        }

        private ImageSource _image = null;
        private String _imagePath = null;
        public ImageSource Image
        {
            get
            {
                if (this._image == null && this._imagePath != null)
                {
                    this._image = new BitmapImage(new Uri(StudentItem._baseUri, this._imagePath));
                }
                return this._image;
            }

            set
            {
                this._imagePath = null;
                this.SetProperty(ref this._image, value);
            }
        }

        public void SetImage(String path)
        {
            this._image = null;
            this._imagePath = path;
            this.OnPropertyChanged("Image");
        }

        private string _imageURL = string.Empty;
        public string ImageURL
        {
            get { return this._imageURL; }
            set { this.SetProperty(ref this._imageURL, value); }
        }

    }
    #endregion

    public sealed class LiveDataSource
    {
        public static string DatabaseFile { get; set; }
        public static string DatabaseFolder { get; set; }

        private static LiveDataSource _liveDataSource = new LiveDataSource();

        private ObservableCollection<CoursePlanItem> _allCourses = new ObservableCollection<CoursePlanItem>();
        private ObservableCollection<UnitItem> _allUnits = new ObservableCollection<UnitItem>();
        private ObservableCollection<LessonPlanItem> _allLessons = new ObservableCollection<LessonPlanItem>();
        private ObservableCollection<ResourceItem> _allResources = new ObservableCollection<ResourceItem>();
        private ObservableCollection<SharedMaterialsItem> _allSharedMaterials = new ObservableCollection<SharedMaterialsItem>();
        private ObservableCollection<NotifcationItem> _allNotifications = new ObservableCollection<NotifcationItem>();
        private ObservableCollection<TeachersGroup> _allTeachers = new ObservableCollection<TeachersGroup>();
        private ObservableCollection<StudentsGroup> _allStudents = new ObservableCollection<StudentsGroup>();
        

        public ObservableCollection<CoursePlanItem> AllCourses
        {
            get { return this._allCourses; }
        }
        public ObservableCollection<UnitItem> AllUnits
        {
            get { return this._allUnits; }
        }
        public ObservableCollection<LessonPlanItem> AllLessons
        {
            get { return this._allLessons; }
        }
        public ObservableCollection<ResourceItem> AllResources
        {
            get { return this._allResources; }
        }
        public ObservableCollection<SharedMaterialsItem> AllSharedMaterials
        {
            get { return this._allSharedMaterials; }
        }
        public ObservableCollection<NotifcationItem> AllNotifications
        {
            get { return this._allNotifications; }
        }
        public ObservableCollection<TeachersGroup> AllTeachers
        {
            get { return this._allTeachers; }
        }
        public ObservableCollection<StudentsGroup> AllStudents
        {
            get { return this._allStudents; }
        }

        internal static ObservableCollection<HubGroups.HubGroup> GetHubGroups(string query)
        {
            ObservableCollection<HubGroups.HubGroup> items = new ObservableCollection<HubGroups.HubGroup>();
            var resourceLoader = new ResourceLoader("Resources");

            var favourites = new HubGroups.Favorites(resourceLoader.GetString("FavoritesTitle"));
            var lessonPlans = new HubGroups.LessonPlans(resourceLoader.GetString("CoursesTitle"));
            var teachers = new HubGroups.Teachers(resourceLoader.GetString("TeachersTitle"));
            var students = new HubGroups.Students(resourceLoader.GetString("ClassMatesTitle"));
            var notifications = new HubGroups.Notifications(resourceLoader.GetString("NotificationsTitle"));
            var sharedMaterials = new HubGroups.SharedMaterials(resourceLoader.GetString("SharedMaterialsTitle"));


            favourites.Items = new ObservableCollection<DataItem>(GetFavoriteResources().Take(9));

            students.Items = new ObservableCollection<DataItem>(GetBudies().Take(10));

            teachers.Items = new ObservableCollection<DataItem>(GetHubTeachers().Take(4));
            var courses = LiveDataSource._liveDataSource.AllCourses;
            IOrderedEnumerable<CoursePlanItem> sortedCourses = courses.OrderBy<CoursePlanItem, string>(cp => cp.Name);
            lessonPlans.Items = new ObservableCollection<DataItem>(sortedCourses);

            notifications.Items = new ObservableCollection<DataItem>(_liveDataSource.AllNotifications.Take(5));

            sharedMaterials.Items = new ObservableCollection<DataItem>(LiveDataSource._liveDataSource.AllSharedMaterials);

            items.Add(notifications);
            items.Add(favourites);
            items.Add(lessonPlans);
            items.Add(sharedMaterials);
            items.Add(students);
            items.Add(teachers);

            return items;
        }

        public static ObservableCollection<DataItem> GetBudies()
        {
            return new ObservableCollection<DataItem>
            {
                new StudentItem("Assets/Students/Ahmed.jpg") { Name = "Amr", Description = "Arabic & English", Email = "amr.elsehemy@hotmail.com", FirstName = "Amr", LastName = "Elsehemy", Subtitle = "Classes in Common:", ColorIndex = 5, ImageURL = "http://qph.is.quoracdn.net/main-thumb-2700592-200-35Mp2X1PNvFBoVfIhx9hLibEGdkvN511.jpeg" },
                new StudentItem("Assets/Students/Ali.jpg") { Name = "Abdelrahman", Description = "English", Email = "sherif.adel@hotmail.com", FirstName = "Sherif", LastName = "Adel", Subtitle = "Classes in Common:", ColorIndex = 5, ImageURL = "http://qph.is.quoracdn.net/main-thumb-2700592-200-35Mp2X1PNvFBoVfIhx9hLibEGdkvN511.jpeg" },
                new StudentItem("Assets/Students/Amran.jpg") { Name = "Ahmad", ImageURL = "https://lh4.googleusercontent.com/-FXqnP1KDePg/ThtOMg_sgeI/AAAAAAAAAE0/O9WmcQtGee8/s347/270383_10150247311926513_554461512_7836073_1066157_n.jpg", Description = "Arabic", Email = "ahmad.almoraly@hotmail.com", FirstName = "Ahmad", LastName = "Almoraly", Subtitle = "Classes in Common:", ColorIndex = 5 },
                new StudentItem("Assets/Students/Khalifa.jpg") { Name = "Kamel", FirstName = "Kamel", LastName = "Nabil", Email = "kamel.nabil@hotmail.com", Subtitle = "Classes in Common:", Description = "Arabic", ColorIndex = 5, ImageURL="https://lh6.googleusercontent.com/-cN3GHNhV7GY/T-L4ooJ0JLI/AAAAAAAAAHc/sbUclDVYses/s800/Me+00+056.JPG"},
                new StudentItem("Assets/Students/Rashed.jpg") { Name = "Akram", Description = "Math", Email = "akram.sayed@hotmail.com", FirstName = "Akram", LastName = "Sayed", Subtitle = "Classes in Common:", ColorIndex = 5, ImageURL = "http://qph.is.quoracdn.net/main-thumb-2700592-200-35Mp2X1PNvFBoVfIhx9hLibEGdkvN511.jpeg" },
                new StudentItem("Assets/Students/Student12.jpg") { Name = "Sherif", Description = "Math", Email = "sherif.adel@hotmail.com", FirstName = "Sherif", LastName = "Adel", Subtitle = "Classes in Common:", ColorIndex = 5, ImageURL = "http://qph.is.quoracdn.net/main-thumb-2700592-200-35Mp2X1PNvFBoVfIhx9hLibEGdkvN511.jpeg" },
                new StudentItem("Assets/Students/Amran.jpg") { Name = "Ahmad", ImageURL = "https://lh4.googleusercontent.com/-FXqnP1KDePg/ThtOMg_sgeI/AAAAAAAAAE0/O9WmcQtGee8/s347/270383_10150247311926513_554461512_7836073_1066157_n.jpg", Description = "Arabic", Email = "ahmad.almoraly@hotmail.com", FirstName = "Ahmad", LastName = "Almoraly", Subtitle = "Classes in Common:", ColorIndex = 5 },
                new StudentItem("Assets/Students/Khalifa.jpg") { Name = "Kamel", FirstName = "Kamel", LastName = "Nabil", Email = "kamel.nabil@hotmail.com", Subtitle = "Classes in Common:", Description = "Arabic", ColorIndex = 5, ImageURL="https://lh6.googleusercontent.com/-cN3GHNhV7GY/T-L4ooJ0JLI/AAAAAAAAAHc/sbUclDVYses/s800/Me+00+056.JPG"},
                new StudentItem("Assets/Students/Rashed.jpg") { Name = "Akram", Description = "Math", Email = "akram.sayed@hotmail.com", FirstName = "Akram", LastName = "Sayed", Subtitle = "Classes in Common:", ColorIndex = 5, ImageURL = "http://qph.is.quoracdn.net/main-thumb-2700592-200-35Mp2X1PNvFBoVfIhx9hLibEGdkvN511.jpeg" },
                new StudentItem("Assets/Students/Student12.jpg") { Name = "Sherif", Description = "Math", Email = "sherif.adel@hotmail.com", FirstName = "Sherif", LastName = "Adel", Subtitle = "Classes in Common:", ColorIndex = 5, ImageURL = "http://qph.is.quoracdn.net/main-thumb-2700592-200-35Mp2X1PNvFBoVfIhx9hLibEGdkvN511.jpeg" },
                new StudentItem("Assets/Students/Ahmed.jpg") { Name = "Amr", Description = "Arabic & English", Email = "amr.elsehemy@hotmail.com", FirstName = "Amr", LastName = "Elsehemy", Subtitle = "Classes in Common:", ColorIndex = 5, ImageURL = "http://qph.is.quoracdn.net/main-thumb-2700592-200-35Mp2X1PNvFBoVfIhx9hLibEGdkvN511.jpeg" },
                new StudentItem("Assets/Students/Ali.jpg") { Name = "Abdelrahman", Description = "English", Email = "sherif.adel@hotmail.com", FirstName = "Sherif", LastName = "Adel", Subtitle = "Classes in Common:", ColorIndex = 5, ImageURL = "http://qph.is.quoracdn.net/main-thumb-2700592-200-35Mp2X1PNvFBoVfIhx9hLibEGdkvN511.jpeg" },
                new StudentItem("Assets/Students/Amran.jpg") { Name = "Ahmad", ImageURL = "https://lh4.googleusercontent.com/-FXqnP1KDePg/ThtOMg_sgeI/AAAAAAAAAE0/O9WmcQtGee8/s347/270383_10150247311926513_554461512_7836073_1066157_n.jpg", Description = "Arabic", Email = "ahmad.almoraly@hotmail.com", FirstName = "Ahmad", LastName = "Almoraly", Subtitle = "Classes in Common:", ColorIndex = 5 },
                new StudentItem("Assets/Students/Khalifa.jpg") { Name = "Kamel", FirstName = "Kamel", LastName = "Nabil", Email = "kamel.nabil@hotmail.com", Subtitle = "Classes in Common:", Description = "Arabic", ColorIndex = 5, ImageURL="https://lh6.googleusercontent.com/-cN3GHNhV7GY/T-L4ooJ0JLI/AAAAAAAAAHc/sbUclDVYses/s800/Me+00+056.JPG"},
                new StudentItem("Assets/Students/Rashed.jpg") { Name = "Akram", Description = "Math", Email = "akram.sayed@hotmail.com", FirstName = "Akram", LastName = "Sayed", Subtitle = "Classes in Common:", ColorIndex = 5, ImageURL = "http://qph.is.quoracdn.net/main-thumb-2700592-200-35Mp2X1PNvFBoVfIhx9hLibEGdkvN511.jpeg" },
                new StudentItem("Assets/Students/Student12.jpg") { Name = "Sherif", Description = "Math", Email = "sherif.adel@hotmail.com", FirstName = "Sherif", LastName = "Adel", Subtitle = "Classes in Common:", ColorIndex = 5, ImageURL = "http://qph.is.quoracdn.net/main-thumb-2700592-200-35Mp2X1PNvFBoVfIhx9hLibEGdkvN511.jpeg" },
                new StudentItem("Assets/Students/Student13.jpg") { Name = "Ahmad", ImageURL = "https://lh4.googleusercontent.com/-FXqnP1KDePg/ThtOMg_sgeI/AAAAAAAAAE0/O9WmcQtGee8/s347/270383_10150247311926513_554461512_7836073_1066157_n.jpg", Description = "Science", Email = "ahmad.almoraly@hotmail.com", FirstName = "Ahmad", LastName = "Almoraly", Subtitle = "Classes in Common:", ColorIndex = 5 },
                new StudentItem("Assets/Students/Student14.jpg") { Name = "Ramy", Description = "Math", FirstName = "Ramy", LastName = "Medhat", Subtitle = "Classes in Common:", Email = "ramy.medhat@hotmail.com", ColorIndex = 4, ImageURL = "https://uwaterloo.ca/embedded-software-group/sites/ca.embedded-software-group/files/uploads/images/Ramy-Medhat_1.jpg" },
                
            };
        }

        public static ObservableCollection<DataItem> GetHubTeachers()
        {
            return new ObservableCollection<DataItem>
            {
                new TeacherItem("Assets/Teachers/manteacher1.jpg") { FirstName = "Abdallah", LastName = "Sameh", Description = "Arabic Teacher",Email = "abdallah.sameh@hotmail.com", ImageURL = "http://a0.twimg.com/profile_images/2422096641/ablqp7zzx9bk78kdzw0v_reasonably_small.jpeg"},                
                new TeacherItem("Assets/Teachers/womenteacher1.jpg") {  FirstName = "Khadija", LastName = "Mohamed",Description = "English Teacher", Email = "khadija.mohamed@hotmail.com", ImageURL = "http://profile.ak.fbcdn.net/hprofile-ak-snc6/260968_551702233_1088605994_n.jpg"},
                new TeacherItem("Assets/Teachers/manteacher2.jpg") { FirstName = "Ahmed", LastName = "Kareem",Description = "Science Teacher", Email = "ahmed.kareem@hotmail.com", ImageURL = "http://profile.ak.fbcdn.net/hprofile-ak-snc6/260968_551702233_1088605994_n.jpg"},
                new TeacherItem("Assets/Teachers/manteacher3.jpg") { FirstName = "Youssef", LastName = "Abdallah", Description = "Math Teacher",Email = "Youssef.Abdallah@hotmail.com", ImageURL = "http://a0.twimg.com/profile_images/2422096641/ablqp7zzx9bk78kdzw0v_reasonably_small.jpeg"},
                
            };
        }



        public async Task LoadAllData()
        {
            await LoadCachedData();

            // only ping the server if we have a network connection
            //ConnectionProfile profile = NetworkInformation.GetInternetConnectionProfile();
            //if (profile != null)
            //    await LoadRemoteData();
        }

        private async Task LoadCachedData()
        {
            // load the disk cache while we wait for the server to respond
            // load from database
            await ReadDataFromDB();
            await ReadLatestNotificationsFromDB();
            await ReadSharedMaterialsFromDB();
            ReadUsers();

        }
        private async Task LoadRemoteData()
        {
            // Later call CLG .. next phase
            await Task.Run(() =>
            {
                for (double i = 0; i < 9999; i++)
                {

                }
            });
        }

        private async Task ReadDataFromDB()
        {
            StorageFile dbFile = await StorageFile.GetFileFromPathAsync(Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "StudentLive.sqlite"));
            LiveDataSource.DatabaseFile = dbFile.Path;

            using (SQLiteConnection db = new SQLiteConnection(DatabaseFile))
            {

                var coursePlanQuery = db.Table<SqlCoursePlan>();
                var coursePlanResult = coursePlanQuery.ToList<SqlCoursePlan>();

                foreach (var coursePlan in coursePlanResult)
                {
                    var cpItem = new CoursePlanItem(coursePlan);
                    var unitsQuery = db.Table<SqlUnit>();
                    var unitsResult = unitsQuery.Where<SqlUnit>(u => u.CoursePlanID == coursePlan.CoursePlanID).ToList<SqlUnit>();

                    foreach (var unit in unitsResult)
                    {
                        var uItem = new UnitItem(unit);

                        var lessonsQuery = db.Table<SqlLessonPlan>();
                        var lessonsResult = lessonsQuery.Where<SqlLessonPlan>(l => l.UnitID == unit.UnitID).ToList<SqlLessonPlan>();

                        foreach (var lesson in lessonsResult)
                        {
                            var lItem = new LessonPlanItem(lesson);
                            var resourcesQuery = db.Table<SqlLearningResource>();
                            var resourcesResult = resourcesQuery.Where<SqlLearningResource>(lr => lr.LessonPlanID == lesson.LessonPlanID).ToList<SqlLearningResource>();

                            foreach (var resource in resourcesResult)
                            {
                                var rItem = new ResourceItem(resource);
                                rItem.Lesson = lItem;
                                lItem.Resources.Add(rItem);
                                this.AllResources.Add(rItem);
                            }

                            lItem.Unit = uItem;
                            uItem.Lessons.Add(lItem);
                            uItem.Lessons.Add(lItem);
                            uItem.Lessons.Add(lItem);
                            this.AllLessons.Add(lItem);
                        }

                        uItem.CoursePlan = cpItem;
                        cpItem.Units.Add(uItem);
                        cpItem.Units.Add(uItem);
                        this.AllUnits.Add(uItem);
                    }

                    this.AllCourses.Add(cpItem);
                }
            }
        }

        public async Task ReadSharedMaterialsFromDB()
        {
            StorageFile dbFile = await StorageFile.GetFileFromPathAsync(LiveDataSource.DatabaseFile);

            List<SqlSharedMaterials> result;

            using (SQLiteConnection db = new SQLiteConnection(DatabaseFile))
            {

                var table = db.Table<SqlSharedMaterials>();
                result = table.ToList<SqlSharedMaterials>();
            }

            foreach (SqlSharedMaterials item in result)
            {
                this.AllSharedMaterials.Add(new SharedMaterialsItem(item));

            }

        }


        public void ReadUsers()
        {

            this.AllTeachers.Add(new TeachersGroup());
            this.AllStudents.Add(new StudentsGroup());

        }

        public async Task ReadLatestNotificationsFromDB()
        {
            StorageFile dbFile = await StorageFile.GetFileFromPathAsync(LiveDataSource.DatabaseFile);

            List<SqlNotifications> result;

            using (SQLiteConnection db = new SQLiteConnection(DatabaseFile))
            {

                var table = db.Table<SqlNotifications>();
                result = table.ToList<SqlNotifications>();
            }

            foreach (SqlNotifications item in result)
            {
                this.AllNotifications.Add(new NotifcationItem(item));

            }

        }

        public static CoursePlanItem GetCoursePlan(int coursePlanID)
        {
            return _liveDataSource.AllCourses.FirstOrDefault<CoursePlanItem>(cp => cp.CoursePlanID == coursePlanID);
        }

        public static UnitItem GetUnit(int unitID)
        {
            return _liveDataSource.AllUnits.FirstOrDefault<UnitItem>(u => u.UnitID == unitID);
        }

        public static LessonPlanItem GetLessonPlan(int lessonPlanID)
        {
            return _liveDataSource.AllLessons.FirstOrDefault<LessonPlanItem>(lp => lp.LessonPlanID == lessonPlanID);
        }

        public static ResourceItem GetLearningResource(string learningResourceGUID)
        {
            return _liveDataSource.AllResources.FirstOrDefault<ResourceItem>(lr => lr.ResourceGUID == learningResourceGUID);
        }

        public static SortedSet<string> GetLearningResourceFileExtensionsOfLessonPlan(LessonPlanItem lessonPlan)
        {
            SortedSet<string> files = new SortedSet<string>();
            var list = lessonPlan.Resources.Select<ResourceItem, string>(ext => ext.Name.Split('.').Last());
            files.UnionWith(list);

            return files;
        }

        public static IOrderedEnumerable<ResourceItem> SortResourcesByType(IEnumerable<ResourceItem> resources)
        {
            return resources.OrderBy<ResourceItem, string>(lr => lr.Name.Split('.').Last());
        }

        public static IOrderedEnumerable<ResourceItem> SortResourcesByRate(IEnumerable<ResourceItem> resources)
        {
            return resources.OrderBy<ResourceItem, double>(lr => lr.Rate);
        }

        public static LiveDataSource DataSource { get { return _liveDataSource; } }

        public static IEnumerable<CoursePlanItem> GetAllLessonPlans(string query)
        {
            if (!query.Equals("AllLessonPlans")) throw new ArgumentException("Only 'AllLessonPlans' is supported as a collection of groups");
            return _liveDataSource.AllCourses;
        }

        public static IEnumerable<CoursePlanItem> GetAllCoursePlans(string query)
        {
            if (!query.Equals("AllCoursePlans")) throw new ArgumentException("Only 'AllCoursePlans' is supported as a collection of groups");
            return _liveDataSource.AllCourses;
        }

        public static IEnumerable<UnitItem> GetAllUnits(string query)
        {
            if (!query.Equals("AllUnits")) throw new ArgumentException("Only 'AllUnits' is supported as a collection of groups");
            return _liveDataSource.AllUnits;
        }

        public static IEnumerable<LessonPlanItem> GetAllLessons(string query)
        {
            if (!query.Equals("AllLessons")) throw new ArgumentException("Only 'AllLessons' is supported as a collection of groups");
            return _liveDataSource.AllLessons;
        }

        public static IEnumerable<SharedMaterialsItem> GetAllSharedMaterials(string query)
        {
            if (!query.Equals("AllSharedMaterials")) throw new ArgumentException("Only 'AllSharedMaterials' is supported as a collection of groups");
            return _liveDataSource.AllSharedMaterials;
        }

        public static IEnumerable<NotifcationItem> GetAllNotifications(string query)
        {
            if (!query.Equals("AllNotifications")) throw new ArgumentException("Only 'AllNotifications' is supported as a collection of groups");
            return _liveDataSource.AllNotifications;
        }

        public static ObservableCollection<DataItem> GetFavoriteResources()
        {
            return new ObservableCollection<DataItem>(_liveDataSource.AllResources.Where<ResourceItem>(item => item.IsFavoured));
        }

        public static ObservableCollection<DataItem> GetAllTeachers()
        {
            return new ObservableCollection<DataItem>(_liveDataSource.AllTeachers);        
        }

        public static ObservableCollection<DataItem> GetAllStudents()
        {
            return new ObservableCollection<DataItem>(_liveDataSource.AllStudents);
        }

        #region UpdatingDatabaseAPI

        public static void UpdateCoursePlan(CoursePlanItem coursePlan)
        {
            coursePlan.updateDatabaseItem();
            UpdateSQLObject(coursePlan.DatabaseItem);
        }

        public static void UpdateUnit(UnitItem unit)
        {
            unit.updateDatabaseItem();
            UpdateSQLObject(unit.DatabaseItem);
        }

        public static void UpdateLessonPlan(LessonPlanItem lessonPlan)
        {
            lessonPlan.updateDatabaseItem();
            UpdateSQLObject(lessonPlan.DatabaseItem);
        }

        public static void UpdateLearningResource(ResourceItem learningResource)
        {
            learningResource.updateDatabaseItem();
            UpdateSQLObject(learningResource.DatabaseItem);
        }

        internal static void UpdateSQLObject(object sqlObject)
        {
            using (SQLiteConnection db = new SQLiteConnection(DatabaseFile))
            {
                db.RunInTransaction(() =>
                {
                    db.Update(sqlObject);
                });
            }
        }

        #endregion


        internal static void SaveAll()
        {
            using (SQLiteConnection db = new SQLiteConnection(DatabaseFile))
            {
                db.RunInTransaction(() =>
                {
                    foreach (var item in DataSource.AllCourses)
                    {
                        db.Update(item);
                    }
                    foreach (var item in DataSource.AllUnits)
                    {
                        db.Update(item);
                    }
                    foreach (var item in DataSource.AllLessons)
                    {
                        db.Update(item);
                    }
                    foreach (var item in DataSource.AllResources)
                    {
                        db.Update(item);
                    }
                });
            }
        }

        internal static async Task DownloadResource(ResourceItem learningResource)
        {
            string path = "Data\\" + learningResource.LocalPath;
            // To be removed install sample data..
            StorageFile doc = await StorageFile.GetFileFromPathAsync(Path.Combine(Windows.ApplicationModel.Package.Current.InstalledLocation.Path,
            path));
            // create a subFolder for that item
            StorageFolder localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
            StorageFolder CoursePlanFolder = await localFolder.CreateFolderAsync(path.Split('\\').ElementAt(1)/*Name of The Course*/, CreationCollisionOption.OpenIfExists);
            StorageFolder UnitFolder = await CoursePlanFolder.CreateFolderAsync(path.Split('\\').ElementAt(2)/*Name of The Course*/, CreationCollisionOption.OpenIfExists);
            StorageFolder LessonFolder = await UnitFolder.CreateFolderAsync(path.Split('\\').ElementAt(3)/*Name of The Lesson*/, CreationCollisionOption.OpenIfExists);

            await doc.CopyAsync(LessonFolder, doc.Name, NameCollisionOption.ReplaceExisting);

            await Task.Run(() =>
            {
                for (double i = 0; i < 99999999; i++)
                {

                }
            });

            learningResource.IsDownloaded = true;
            UpdateLearningResource(learningResource);
        }

        public static ObservableCollection<HubGroups.HubGroup> GetAllItemsOfCoursePlan(int coursePlanID)
        {

            ObservableCollection<HubGroups.HubGroup> allItems = new ObservableCollection<HubGroups.HubGroup>();

            CoursePlanItem course = _liveDataSource.AllCourses.FirstOrDefault<CoursePlanItem>(cp => cp.CoursePlanID == coursePlanID);

            foreach (UnitItem unit in course.Units)
            {
                var unitItem = new HubGroups.UnitGroupContent(unit.Name);
                foreach (LessonPlanItem lesson in unit.Lessons)
                {
                    unitItem.Items.Add(lesson);
                    unitItem.MirroredItems.Add(lesson);
                    foreach (var item in lesson.Resources)
                    {
                        unitItem.Items.Add(item);
                        unitItem.MirroredItems.Add(item);
                    }
                }

                allItems.Add(unitItem);
            }

            return allItems;
        }
    }

    #region Database Items

    [SQLite.Table("CoursePlan")]
    public class SqlCoursePlan
    {
        [SQLite.Column("PK_CoursePlan"), SQLite.PrimaryKey]
        public int PrimaryKey { get; set; }

        [SQLite.Column("CoursePlanID")]
        public int CoursePlanID { get; set; }

        [SQLite.Column("Name")]
        public string Name { get; set; }

        [SQLite.Column("ImagePath")]
        public string ImagePath { get; set; }

    }

    [SQLite.Table("Unit")]
    public class SqlUnit
    {
        [SQLite.Column("Icon")]
        public string Icon { get; set; }

        [SQLite.Column("Color")]
        public string Color { get; set; }

        [SQLite.Column("PK_Unit"), SQLite.PrimaryKey]
        public int PrimaryKey { get; set; }

        [SQLite.Column("UnitID")]
        public int UnitID { get; set; }

        [SQLite.Column("CoursePlanID")]
        public int CoursePlanID { get; set; }

        [SQLite.Column("Name")]
        public string Name { get; set; }
    }

    [SQLite.Table("LessonPlan")]
    public class SqlLessonPlan
    {
        [SQLite.Column("PK_LessonPlan"), SQLite.PrimaryKey]
        public int PrimaryKey { get; set; }

        [SQLite.Column("LessonPlanID")]
        public int LessonPlanID { get; set; }

        [SQLite.Column("UnitID")]
        public int UnitID { get; set; }

        [SQLite.Column("Name")]
        public string Name { get; set; }
    }

    [SQLite.Table("LearningResource")]
    public class SqlLearningResource
    {
        [SQLite.Column("PK_LearningResource"), SQLite.PrimaryKey]
        public int PrimaryKey { get; set; }

        [SQLite.Column("LearningResourceName")]
        public string LearningResourceName { get; set; }

        [SQLite.Column("LearningResourceGUID")]
        public string LearningResourceGUID { get; set; }

        [SQLite.Column("LessonPlanID")]
        public int LessonPlanID { get; set; }

        [SQLite.Column("IsDownloaded")]
        public bool IsDownloaded { get; set; }

        [SQLite.Column("IsFavored")]
        public bool IsFavored { get; set; }

        [SQLite.Column("LocalPath")]
        public string LocalPath { get; set; }

        [SQLite.Column("Rate")]
        public double Rate { get; set; }

        [SQLite.Column("Description")]
        public string Description { get; set; }
    }

    [SQLite.Table("Notifications")]
    public class SqlNotifications
    {
        [SQLite.Column("PK_Notifications"), SQLite.PrimaryKey]
        public int PrimaryKey { get; set; }

        [SQLite.Column("Name")]
        public string Name { get; set; }

        [SQLite.Column("Description")]
        public string Description { get; set; }

        [SQLite.Column("Type")]
        public int Type { get; set; }

    }

    [SQLite.Table("SharedMaterials")]
    public class SqlSharedMaterials
    {
        [SQLite.Column("PK_SharedMaterial"), SQLite.PrimaryKey]
        public int PrimaryKey { get; set; }

        [SQLite.Column("SharedMaterialName")]
        public string SharedMaterialName { get; set; }

        [SQLite.Column("SharedMaterialDescription")]
        public string SharedMaterialDescription { get; set; }

        [SQLite.Column("LocalPath")]
        public string LocalPath { get; set; }
    }
    #endregion

}

// Just a new space to avoid name collision in future, since the names are generic.
namespace StudentLive.DataModel.HubGroups
{
    public abstract class HubGroup : DataItem
    {
        public HubGroup()
            : base(String.Empty, String.Empty)
        { }

        public HubGroup(String name, String description)
            : base(name, description)
        {
        }
        private ObservableCollection<DataItem> _items = new ObservableCollection<DataItem>();
        public ObservableCollection<DataItem> Items
        {
            get { return this._items; }
            set { this._items = value; }
        }

        public int Count
        {
            get { return Items.Count; }
        }

    }
    public class Favorites : HubGroup
    {
        public Favorites(string Name)
            : base(Name, "This is the favorites list")
        { ColorIndex = 1; }

        private ImageSource _image;
        public ImageSource Image
        {
            get
            {
                if (_image == null)
                {
                    _image = new BitmapImage(new Uri(DataItem._baseUri, "/Assets/SemanticZoomPics/favorites.jpg"));
                }
                return _image;
            }
        }
    }
    public class LessonPlans : HubGroup
    {
        public LessonPlans(string Name)
            : base(Name, "This is the Lesson Plans list")
        { ColorIndex = 2; }


        private ImageSource _image;
        public ImageSource Image
        {
            get
            {
                if (_image == null)
                {
                    _image = new BitmapImage(new Uri(DataItem._baseUri, "/Assets/SemanticZoomPics/lesson_plan.jpg"));
                }
                return _image;
            }
        }
    }
    public class Teachers : HubGroup
    {
        public Teachers(string Name)
            : base(Name, "This is the teachers list")
        { ColorIndex = 3; }


        private ImageSource _image;
        public ImageSource Image
        {
            get
            {
                if (_image == null)
                {
                    _image = new BitmapImage(new Uri(DataItem._baseUri, "/Assets/SemanticZoomPics/teachers.jpg"));
                }
                return _image;
            }
        }
    }
    public class Students : HubGroup
    {
        public Students(string Name)
            : base(Name, "This is the students list")
        { ColorIndex = 4; }

        private ImageSource _image;
        public ImageSource Image
        {
            get
            {
                if (_image == null)
                {
                    _image = new BitmapImage(new Uri(DataItem._baseUri, "/Assets/SemanticZoomPics/buddies.jpg"));
                }
                return _image;
            }
        }
    }
    public class Notifications : HubGroup
    {
        public Notifications(string Name)
            : base(Name, "This is the notifications list")
        { ColorIndex = 5; }

        private ImageSource _image;
        public ImageSource Image
        {
            get
            {
                if (_image == null)
                {
                    _image = new BitmapImage(new Uri(DataItem._baseUri, "/Assets/SemanticZoomPics/notifi.jpg"));
                }
                return _image;
            }
        }
    }
    public class SharedMaterials : HubGroup
    {
        public SharedMaterials(string Name)
            : base(Name, "This is the Shared Materials list")
        { ColorIndex = 6; }

        private ImageSource _image;
        public ImageSource Image
        {
            get
            {
                if (_image == null)
                {
                    _image = new BitmapImage(new Uri(DataItem._baseUri, "/Assets/SemanticZoomPics/shared_material.jpg"));
                }
                return _image;
            }
        }
    }

    public class UnitGroupContent : HubGroup
    {
        public UnitGroupContent(string name)
            : base(name, name)
        {
        }

        private ObservableCollection<DataItem> _mirroredItems = new ObservableCollection<DataItem>();
        public ObservableCollection<DataItem> MirroredItems
        {
            get
            {
                return this._mirroredItems;
            }
            set { this.SetProperty(ref this._mirroredItems, value); }
        }

        private bool _isCollapsed = false;
        public bool IsCollapsed
        {
            get { return this._isCollapsed; }
            set { this.SetProperty(ref this._isCollapsed, value); }
        }
    }
}